﻿#region License
/***
 * Copyright © 2018-2020, 张强 (943620963@qq.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * without warranties or conditions of any kind, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#endregion

using System;
using System.Reflection;
using Autofac;
using Autofac.Core;
using Autofac.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
/****************************
* [Author] 张强
* [Date] 2018-05-17
* [Describe] IServiceCollection扩展类
* **************************/
namespace ZqUtils.Core.Extensions
{
    /// <summary>
    /// IServiceCollection扩展类
    /// </summary>
    public static partial class Extensions
    {
        #region Private Static Field
        /// <summary>
        /// 私有静态字段
        /// </summary>
        private static readonly ContainerBuilder container = new ContainerBuilder();
        #endregion      

        #region RegisterAutofac
        /// <summary>
        /// 注册Autofac依赖注入
        /// </summary>
        /// <param name="services"></param>
        /// <param name="modules"></param>
        public static void RegisterAutofac(this IServiceCollection services, params IModule[] modules)
        {
            if (modules?.Length > 0)
            {
                foreach (var module in modules)
                {
                    container.RegisterModule(module);
                }
            }
        }

        /// <summary>
        /// 注册Autofac依赖注入
        /// </summary>
        /// <param name="services"></param>
        /// <param name="assemblies"></param>
        public static void RegisterAutofac(this IServiceCollection services, params Assembly[] assemblies)
        {
            if (assemblies?.Length > 0)
            {
                container
                   .RegisterAssemblyTypes(assemblies)
                   .AsImplementedInterfaces()
                   .PropertiesAutowired()
                   .AsSelf();
            }
        }

        /// <summary>
        /// 注册Autofac依赖注入
        /// </summary>
        /// <param name="services"></param>
        /// <param name="predicate"></param>
        /// <param name="assemblies"></param>
        public static void RegisterAutofac(this IServiceCollection services, Func<Type, bool> predicate, params Assembly[] assemblies)
        {
            if (assemblies?.Length > 0)
            {
                container
                   .RegisterAssemblyTypes(assemblies)
                   .Where(predicate)
                   .AsImplementedInterfaces()
                   .PropertiesAutowired()
                   .AsSelf();
            }
        }

        /// <summary>
        /// 注册Autofac依赖注入
        /// </summary>
        /// <param name="services"></param>
        /// <param name="modules"></param>
        /// <param name="assemblies"></param>
        public static void RegisterAutofac(this IServiceCollection services, IModule[] modules, Assembly[] assemblies)
        {
            if (modules?.Length > 0)
            {
                foreach (var module in modules)
                {
                    container.RegisterModule(module);
                }
            }
            if (assemblies?.Length > 0)
            {
                container
                    .RegisterAssemblyTypes(assemblies)
                    .AsImplementedInterfaces()
                    .PropertiesAutowired()
                    .AsSelf();
            }
        }

        /// <summary>
        /// 注册Autofac依赖注入
        /// </summary>
        /// <param name="services"></param>
        /// <param name="modules"></param>
        /// <param name="assemblies"></param>
        /// <param name="predicate"></param>
        public static void RegisterAutofac(this IServiceCollection services, IModule[] modules, Assembly[] assemblies, Func<Type, bool> predicate)
        {
            if (modules?.Length > 0)
            {
                foreach (var module in modules)
                {
                    container.RegisterModule(module);
                }
            }
            if (assemblies?.Length > 0)
            {
                container
                    .RegisterAssemblyTypes(assemblies)
                    .Where(predicate)
                    .AsImplementedInterfaces()
                    .PropertiesAutowired()
                    .AsSelf();
            }
        }
        #endregion

        #region AddAutofac
        /// <summary>
        /// 添加Autofac依赖注入
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceProvider AddAutofac(this IServiceCollection services)
        {
            container.Populate(services);
            return new AutofacServiceProvider(container.Build());
        }

        /// <summary>
        /// 添加Autofac依赖注入
        /// </summary>
        /// <param name="services"></param>
        /// <param name="modules"></param>
        /// <returns></returns>
        public static IServiceProvider AddAutofac(this IServiceCollection services, params IModule[] modules)
        {
            if (modules?.Length > 0)
            {
                foreach (var module in modules)
                {
                    container.RegisterModule(module);
                }
            }
            container.Populate(services);
            return new AutofacServiceProvider(container.Build());
        }

        /// <summary>
        /// 添加Autofac依赖注入
        /// </summary>
        /// <param name="services"></param>
        /// <param name="assemblies"></param>
        /// <returns></returns>
        public static IServiceProvider AddAutofac(this IServiceCollection services, params Assembly[] assemblies)
        {
            if (assemblies?.Length > 0)
            {
                container
                   .RegisterAssemblyTypes(assemblies)
                   .AsImplementedInterfaces()
                   .PropertiesAutowired()
                   .AsSelf();
            }
            container.Populate(services);
            return new AutofacServiceProvider(container.Build());
        }

        /// <summary>
        /// 添加Autofac依赖注入
        /// </summary>
        /// <param name="services"></param>
        /// <param name="predicate"></param>
        /// <param name="assemblies"></param>
        /// <returns></returns>
        public static IServiceProvider AddAutofac(this IServiceCollection services, Func<Type, bool> predicate, params Assembly[] assemblies)
        {
            if (assemblies?.Length > 0)
            {
                container
                   .RegisterAssemblyTypes(assemblies)
                   .Where(predicate)
                   .AsImplementedInterfaces()
                   .PropertiesAutowired()
                   .AsSelf();
            }
            container.Populate(services);
            return new AutofacServiceProvider(container.Build());
        }

        /// <summary>
        /// 添加Autofac依赖注入
        /// </summary>
        /// <param name="services"></param>
        /// <param name="modules"></param>
        /// <param name="assemblies"></param>
        /// <returns></returns>
        public static IServiceProvider AddAutofac(this IServiceCollection services, IModule[] modules, Assembly[] assemblies)
        {
            if (modules?.Length > 0)
            {
                foreach (var module in modules)
                {
                    container.RegisterModule(module);
                }
            }
            if (assemblies?.Length > 0)
            {
                container
                       .RegisterAssemblyTypes(assemblies)
                       .AsImplementedInterfaces()
                       .PropertiesAutowired()
                       .AsSelf();
            }
            container.Populate(services);
            return new AutofacServiceProvider(container.Build());
        }

        /// <summary>
        /// 添加Autofac依赖注入
        /// </summary>
        /// <param name="services"></param>
        /// <param name="modules"></param>
        /// <param name="assemblies"></param>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public static IServiceProvider AddAutofac(this IServiceCollection services, IModule[] modules, Assembly[] assemblies, Func<Type, bool> predicate)
        {
            if (modules?.Length > 0)
            {
                foreach (var module in modules)
                {
                    container.RegisterModule(module);
                }
            }
            if (assemblies?.Length > 0)
            {
                container
                    .RegisterAssemblyTypes(assemblies)
                    .Where(predicate)
                    .AsImplementedInterfaces()
                    .PropertiesAutowired()
                    .AsSelf();
            }
            container.Populate(services);
            return new AutofacServiceProvider(container.Build());
        }
        #endregion
    }
}
